package org.example.service;

import org.example.entity.User;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 定制消息组件
 */
@Service
public class MessageProducerService {

    // 用于管理 AMQP 元素，如交换机、队列和绑定
    private AmqpAdmin amqpAdmin;
    // 用于发送和接收消息到 RabbitMQ
    private RabbitTemplate rabbitTemplate;

    /**
     * 构造函数，使用主题交换机模式初始化消息队列和绑定
     * @param amqpAdmin 用于管理 AMQP 元素的组件
     * @param rabbitTemplate 用于与 RabbitMQ 交互的模板
     */
    @Autowired
    public MessageProducerService(AmqpAdmin amqpAdmin, RabbitTemplate rabbitTemplate) {
        this.amqpAdmin = amqpAdmin;
        this.rabbitTemplate = rabbitTemplate;
        // 创建一个主题交换机，名为 "topic_exchange"
        this.amqpAdmin.declareExchange(new TopicExchange("topic_exchange"));
        // 创建一个名为 "topic.email.queue" 的队列
        this.amqpAdmin.declareQueue(new Queue("topic.email.queue"));
        // 创建一个名为 "topic_sms_queue" 的队列
        this.amqpAdmin.declareQueue(new Queue("topic_sms_queue"));
        // 将 "topic.email.queue" 队列绑定到 "topic_exchange" 交换机上
        this.amqpAdmin.declareBinding(new Binding("topic.email.queue", Binding.DestinationType.QUEUE, "topic_exchange", "", null));
        // 将 "topic_sms_queue" 队列绑定到 "topic_exchange" 交换机上
        this.amqpAdmin.declareBinding(new Binding("topic_sms_queue", Binding.DestinationType.QUEUE, "topic_exchange", "", null));
    }

    /**
     * 发布消息到发布/订阅交换机
     * @param user 要发送的用户对象
     */
    public void psubPublisher(User user) {
        // 把用户对象发送到名为 "pub/sub.exchange" 的交换机，使用空路由键
        this.rabbitTemplate.convertAndSend("pub/sub.exchange", "", user);
    }

    /**
     * 发布消息到路由交换机，使用 "error_routing_key" 路由键
     * @param message 要发送的消息内容
     */
    public void routingPublisher(String message) {
        rabbitTemplate.convertAndSend("routing_exchange",
                "error_routing_key",
                message);
    }

    /**
     * 发布消息到路由交换机，使用 "info_routing_key" 路由键
     * @param message 要发送的消息内容
     */
    public void routingPublisher2(String message) {
        rabbitTemplate.convertAndSend("routing_exchange",
                "info_routing_key",
                message);
    }

    /**
     * 发布消息到路由交换机，使用指定的路由键
     * @param key 指定的路由键
     * @param message 要发送的消息内容
     */
    public void routingPublisher3(String key, String message) {
        rabbitTemplate.convertAndSend("routing_exchange",
                key,
                message);
    }

    /**
     * 发布消息到主题交换机，使用指定的路由键
     * @param routingKey 指定的路由键
     * @param message 要发送的消息内容
     */
    public void TopicPublisher(String routingKey, String message) {
        rabbitTemplate.convertAndSend("topic_exchange",
                routingKey,
                message);
    }
}
